package com.trans.core;

import com.trans.anno.IgnoreTrans;
import com.trans.anno.TransTemplate;
import com.trans.anno.Translator;
import com.trans.auxiliary.HandleFullRecord;
import com.trans.auxiliary.Params;
import com.trans.auxiliary.TranslatorAbleHelper;
import com.trans.auxiliary.TranslatorRecord;
import com.trans.contants.TranslatorConfig;
import com.trans.entity.TransEntity;
import com.trans.handler.GlobalTranslateHandle;
import com.trans.handler.TranslateHandle;
import com.trans.utils.MapUtils;
import com.trans.utils.ParamsUtils;
import com.trans.utils.TypeUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @Author xwduo
 * @Description //TODO
 * @Date 2022-10-31 17:42
 */
@Slf4j
@SuppressWarnings("all")
public class TranslateUtils {

    private static final Map<Class<? extends TranslateHandle>, TranslateHandle> instanceMap = new HashMap<>();

    /**
     * 参数数据key（预留）
     */
    public static final String PARAMS_CACHE="paramsCache";

    /**
     * 全局翻译功能，支持Rs
     * Rs结构
     * {"code":0,"msg":"ok","success":true,"data": T }
     * T: IPage分页对象、Collection集合、T自定义Class类型
     * 翻译目标：带PageJson注解的字段
     * 翻译方法：对应的JsonHandle
     * 2022-11-01 更新
     * @ TransTemplate
     * 支持模板对象，默认为ModelClass
     */
    protected static Object doTranslate(Object data, TransTemplate modelJson, Class defaultClass) {
        if (null != data) {
            //翻译数据缓存集合
            Map<String, Object> otherMap = new HashMap<>();
            //翻译待处理数据
            Map<Class<? extends TranslateHandle>, List<HandleFullRecord>> handleRecordMap = new HashMap<>();
            //遍历需要翻译的字段
            long time1=System.currentTimeMillis();
            //获取需要记录的数据
            TranslatorRecord record = new TranslatorRecord(data, data, handleRecordMap, otherMap, null , modelJson,defaultClass);
            Object returnData = searchTranslateData(record);
            long time2=System.currentTimeMillis();
            log.info("提取翻译字段 耗时："+(time2-time1)+"ms");
            //翻译
            try {
                List<TranslateHandle> jsonHandles = fetchSortHandle(handleRecordMap.keySet());
                for (TranslateHandle handleInstance : jsonHandles) {
                    Class<? extends TranslateHandle> handleClass = handleInstance.getClass();
                    List<HandleFullRecord> value = handleRecordMap.get(handleClass);
                    try {
                        // 实例化这个类
                        Map cacheMap = handleInstance.cache(value);
                        for (HandleFullRecord handleFullRecord : value) {
                            // 调用指定方法
                            handleInstance.handle(handleFullRecord, cacheMap );
                        }
                    } catch (Exception e) {
                        log.error("无法转换中文字段，查无该转换处理类", e);
                    }
                }
            }catch (Exception e){
                log.error("无法获取处理器顺序：{}",e.getMessage(),e);
                return data;
            }
            long time3=System.currentTimeMillis();
            log.info("执行翻译 耗时："+(time3-time2)+"ms");
            return returnData;
        }
        return data;
    }




    /**
     * @Description: 查找需要翻译的数据(入口方法)
     * @Author: xwduo
     * @Date: 2022-10-28 17:12
     * @param：
     * obj: 传入的数据
     * items: 预留替换列表
     * handleRecordMap: 记录翻译数据的Map
     * otherMap: 预留参数列表
     */
    static  Object searchTranslateData(TranslatorRecord translatorRecord) {
        Object obj = translatorRecord.curObj;
        Object returnData = null;
        if (null != obj) {
            //判断是否为集合
            if (obj instanceof Collection) {
                Collection objCollection = (Collection) obj;
                List returnDataList = new ArrayList();
                for (Object o : objCollection) {
                    Object singleReturnData = searchTranslateData( translatorRecord.copy(o));
                    returnDataList.add(singleReturnData);
                }
                returnData = returnDataList;
            //判断是否为Map
            } else if(obj instanceof Map){
                returnData = MapJsonUtils.recordMap( translatorRecord.copy(obj));
            //是否为
            } else if (TypeUtils.isCustomClass(obj)) {
                TranslatorRecord subTranslatorRecord = translatorRecord.copyNewMap(obj);
                returnData = subTranslatorRecord.subEntry;
                Map<Class<? extends TranslateHandle>, List<HandleFullRecord>> handleMap = doSearch(subTranslatorRecord);
                MapUtils.combine(translatorRecord.handleRecordMap,handleMap);
            } else {
                returnData = obj;
            }
        }
        return returnData;
    }


    /**
     * @Description: 记录自定义实体类
     * @Author: xwduo
     * @Date: 2022-10-28 17:21
     * @param：
     * fullObj：原始返回值
     * record: 原始-当前层级数据对象（单个对象，非集合）
     * item: 记录对象
     * otherMap: 当前全局存储数据对象
     * modelJson：模板对象
     * * @return Map<Class<List<HandleRecord>>
     */
    static Map<Class<? extends TranslateHandle>, List<HandleFullRecord>> doSearch(TranslatorRecord translatorRecord) {
        Object originObj = translatorRecord.curObj;
        Map<String, Object> item = translatorRecord.subEntry;
        Object fullObj = translatorRecord.fullObject;
        Map<Class<? extends TranslateHandle>, List<HandleFullRecord>> handleRecordMap = new HashMap<>();
        if( null != originObj ){
            //获取该originObj的所有字段
            boolean exist = translatorRecord.checkCodeExistAndRecord(originObj);
            List<Params> params = ParamsUtils.getAllPossibilityFields(originObj);
            for (Params param : params) {
                if( null == param.getAnnotation(IgnoreTrans.class) ){
                    int modifiers = param.modifier;
                    boolean translatorDisable = TranslatorAbleHelper.deny(modifiers) ;
                    if( !translatorDisable && (TranslatorAbleHelper.tran2Map || originObj instanceof TransEntity)){
                        //获取值
                        Object value  = param.findObjectVal(originObj);
                        if(TranslatorAbleHelper.nullAble(value)) {
                            if (value instanceof Collection) {
                                //对象是个集合，获取数据
                                List items = new ArrayList();
                                value = searchTranslateData(translatorRecord.copy(value));
                            } else if(value instanceof Map){
                                //如果是个Map 记录
                                value = MapJsonUtils.recordMap(translatorRecord.copy(value));
                            } else {
                                if(!TranslatorConfig.GLOBAL_TYPE_HANDLE.isEmpty()){
                                    Class<? extends TranslateHandle> classTranslator = TranslatorConfig.GLOBAL_TYPE_HANDLE.get(value.getClass());
                                    if(null != classTranslator){
                                        HandleFullRecord handleRecord = new HandleFullRecord(null, param , item, originObj ,  fullObj);
                                        MapUtils.putIfExist(handleRecordMap,classTranslator, handleRecord);
                                    }
                                }
                                if(!TranslatorConfig.GLOBAL_CUSTOM_HANDLE.isEmpty()){
                                    List<GlobalTranslateHandle> globalCustomHandle = TranslatorConfig.GLOBAL_CUSTOM_HANDLE;
                                    for (GlobalTranslateHandle globalTranslateHandle : globalCustomHandle) {
                                        if(null != globalTranslateHandle.handle){
                                            boolean isSupport = globalTranslateHandle.support(value);
                                            if( isSupport ){
                                                HandleFullRecord handleRecord = new HandleFullRecord(null, param , item, originObj ,  fullObj);
                                                MapUtils.putIfExist(handleRecordMap,globalTranslateHandle.handle, handleRecord);
                                            }
                                        }

                                    }
                                }
                                //判断是否为自定义类型
                                if (TypeUtils.isCustomClass(param.type)) {
                                    //如果还是自定义类，是则预设对象
                                    TranslatorRecord subTranslatorRecord = translatorRecord.copyNewMap(value);
                                    value = subTranslatorRecord.subEntry;
                                    //记录对象
                                    Map<Class<? extends TranslateHandle>, List<HandleFullRecord>> handleMap = doSearch(subTranslatorRecord);
                                    MapUtils.combine(handleRecordMap,handleMap);
                                } else {
                                    //当存在默认模板时
                                    Map<String, HandleFullRecord> modelMap = translatorRecord.getModelMap();
                                    Translator customFormat = param.getAnnotation(Translator.class);
                                    if (null == customFormat && null != modelMap && modelMap.containsKey(param.name))  {
                                        HandleFullRecord handleFullRecord = modelMap.get(param.name);
                                        customFormat = handleFullRecord.translator;
                                    }
                                    if(null != customFormat){
                                        Class<? extends TranslateHandle>[] handleClasses = customFormat.tranHandle();
                                        HandleFullRecord handleRecord = new HandleFullRecord(customFormat, param , item, originObj,  fullObj);
                                        for (Class<? extends TranslateHandle> handleClass : handleClasses) {
                                            MapUtils.putIfExist(handleRecordMap, handleClass, handleRecord);
                                        }
                                    }
                                }
                            }
                        }
                        //空值便赋值为null
                        item.put(param.name, value);
                    }
                }
            }
        }
        return handleRecordMap;
    }

    private static void cacheJsonHandle(Set<Class<? extends TranslateHandle>> handleSet) throws IllegalAccessException,InstantiationException{
        for (Class<? extends TranslateHandle> aClass : handleSet) {
            if(! instanceMap.containsKey(aClass)){
                instanceMap.put(aClass,aClass.newInstance());
            }
        }
    }
    
    private static List<TranslateHandle> fetchSortHandle(Set<Class<? extends TranslateHandle>> handleSet) throws IllegalAccessException,InstantiationException {
        cacheJsonHandle(handleSet);
        List<TranslateHandle> sortHandle = new ArrayList<>();
        for (Class<? extends TranslateHandle> aClass : handleSet) {
            sortHandle.add(instanceMap.get(aClass));
        }
        sortHandle.sort(Comparator.comparingInt(TranslateHandle::order));
        return sortHandle;
    }
}
